package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.core.ClientBuilder;
import com.huaweicloud.sdk.core.auth.AbstractCredentials;
import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.core.region.Region;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.core.domain.AjaxResult;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.config.IotClientConfig;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.dto.ElderHealthDto;
import com.zzyl.nursing.dto.MemberElderDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.service.IFamilyMemberElderService;
import com.zzyl.nursing.vo.DeviceDataDailyVo;
import com.zzyl.nursing.vo.FamilyMemberElderVo;
import com.zzyl.nursing.vo.MemberElderVo;
import com.zzyl.nursing.vo.health.ElderHealthVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 * @Description FamilyMemberElderServiceImpl
 * @Author yhy
 * @Date 2025-03-02 17:03
 */
@Service
public class FamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper, FamilyMemberElder> implements IFamilyMemberElderService {
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;
    @Autowired
    private IoTDAClient iotDAClient;
    @Autowired
    private DeviceDataMapper deviceDataMapper;
    @Value("${huaweicloud.ak}")
    private String ak;

    @Value("${huaweicloud.sk}")
    private String sk;

    @Value("${huaweicloud.regionId}")
    private String region;

    @Value("${huaweicloud.projectId}")
    private String projectId;

    @Value("${huaweicloud.endpoint}")
    private String endpoint;
    @Override
    public FamilyMemberElder selectFamilyMemberElderById(Long id) {
        return null;
    }

    @Override
    public List<FamilyMemberElder> selectFamilyMemberElderList(FamilyMemberElder familyMemberElder) {
        return null;
    }

    @Override
    public int insertFamilyMemberElder(FamilyMemberElder familyMemberElder) {
        return 0;
    }

    @Override
    public int updateFamilyMemberElder(FamilyMemberElder familyMemberElder) {
        return 0;
    }

    @Override
    public int deleteFamilyMemberElderByIds(Long[] ids) {
        return 0;
    }

    @Override
    public int deleteFamilyMemberElderById(Long id) {
        return 0;
    }

    @Override
    public int add(MemberElderDto memberElderDto) {
        //根据身份证号查询老人
        LambdaQueryWrapper<Elder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Elder::getIdCardNo,memberElderDto.getIdCard());
        Elder elder = elderMapper.selectOne(lambdaQueryWrapper);

        //判断老人是否存在
        if(ObjectUtil.isEmpty(elder)){
            throw new BaseException("该老人未入住，请检查输入信息");
        }

        //当前登录人
        Long userId = UserThreadLocal.getUserId();

        //判断是否已经绑定
        long count = count(Wrappers.<FamilyMemberElder>lambdaQuery()
                .eq(FamilyMemberElder::getElderId, elder.getId())
                .eq(FamilyMemberElder::getFamilyMemberId, userId));
        if(count > 0){
            throw new BaseException("该老人已绑定，请勿重复绑定");
        }


        //保存家属与老人的关系
        FamilyMemberElder familyMemberElder = BeanUtil.toBean(memberElderDto, FamilyMemberElder.class);
        familyMemberElder.setElderId(elder.getId());
        familyMemberElder.setFamilyMemberId(UserThreadLocal.getUserId());
        return save(familyMemberElder) ? 1 : 0;
    }


    @Override
    public List<FamilyMemberElderVo> my() {
        Long userId = UserThreadLocal.getUserId();
        List<FamilyMemberElderVo> list = familyMemberElderMapper.selectMyMemberElder(userId);
        return list;
    }

    @Override
    public List<MemberElderVo> listByPage(Long userId) {
        return familyMemberElderMapper.listByPage(userId);
    }

    @Override
    public int deleteById(Long id) {
        return 0;
    }

    @Autowired
    private IotClientConfig iotClientConfig;
  @Override
public AjaxResult queryDevicePropertyStatus(String iotId) {
    // 获取华为IOT客户端实例
    /*ICredential auth = new BasicCredentials()
            .withProjectId(projectId)
            .withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE)
            .withAk(ak)
            .withSk(sk);
    IoTDAClient client = IoTDAClient.newBuilder()
            .withCredential(auth)
            .withRegion(new Region("cn-north-4", endpoint))
            .build();

    ShowDeviceRequest request = new ShowDeviceRequest();
    request.withDeviceId(elderHealthDto.getIdentifier());  // 假设 ElderHealthDto 中有 deviceId 字段

    List<ElderHealthVo> elderHealthVos = new ArrayList<>();

    try {
        ShowDeviceResponse response = client.showDevice(request);

        // 解析响应数据并转换为 ElderHealthVo 对象
        // 假设 ShowDeviceResponse 中有 getProperties() 方法返回设备属性
        // 并且 ElderHealthVo 有一个构造函数或静态方法可以从这些属性创建对象
        *//*if (response != null && response.getProductId() != null) {
            for (Map<String, Object> property : response.getProperties()) {
                ElderHealthVo elderHealthVo = ElderHealthVo.fromPropertyMap(property);
                elderHealthVos.add(elderHealthVo);
            }
        }*//*

    } catch (BaseException e) {
        e.printStackTrace();
        // 可以选择抛出异常或者记录日志
    }

    return elderHealthVos;*/

      //1.定义返回数据对象List<Map<String,Object>>用于封装返回
      List<Map<String,Object>> data = new ArrayList<>();

      //2.远程调用IOT查询设备影子上报数据
      ShowDeviceShadowRequest request = new ShowDeviceShadowRequest();
      request.withDeviceId(iotId);
      ShowDeviceShadowResponse response = null;
      try {
          response = iotDAClient.showDeviceShadow(request);
      }catch(Exception e){
          log.error("查询华为IOT设备影子失败："+e.getMessage());
          e.printStackTrace();
          throw new RuntimeException("查询华为IOT设备影子失败："+e.getMessage());
      }
      if(response.getHttpStatusCode() != 200) {
          log.error("查询华为IOT设备影子失败");
          throw new RuntimeException("查询华为IOT设备影子失败");
      }
      //3.解析设备影子数据，封装到List<Map<String,Object>>中
      DeviceShadowProperties reported = response.getShadow().get(0).getReported();
      if(ObjectUtil.isNotEmpty(reported)){
          LinkedHashMap<String,Object> properties = (LinkedHashMap<String,Object>)reported.getProperties();
          properties.forEach((key,value)->{
              Map<String,Object> map = new HashMap<>();
              map.put("functionId",key);
              map.put("value",value);

              String eventTimeStr = reported.getEventTime();
              if(StrUtil.isNotEmpty(eventTimeStr)) {

                  LocalDateTime eventTime =  LocalDateTimeUtil.parse(eventTimeStr, "yyyyMMdd'T'HHmmss'Z'");
                  //日期时区转换
                  //日期时区转换
                  eventTime = eventTime.atZone(ZoneId.from(ZoneOffset.UTC))
                          .withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                          .toLocalDateTime();
                  map.put("eventTime",eventTime);
              }
              //将map添加到List<Map<String,Object>>中
              data.add(map);
          });
      }else{
          return AjaxResult.warn("暂无最新上报数据");
      }

      //4.封装AjaxResult返回
      return AjaxResult.success(data);
}

    @Override
    public List<DeviceDataDailyVo> queryDeviceDataListByDay(String iotId, Long startTime, Long endTime, String functionId) {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
      // 将时间戳转换为 LocalDateTime 类型
        LocalDateTime startDateTime = convertTimestampToLocalDateTime(startTime);
        LocalDateTime endDateTime = convertTimestampToLocalDateTime(endTime);

        // 格式化 LocalDateTime 为字符串
        String startTimestamp = startDateTime.format(formatter);
        String endTimestamp = endDateTime.format(formatter);

        List<DeviceData> deviceDataList = deviceDataMapper.selectDeviceDataByDay(iotId, startTimestamp, endTimestamp, functionId);

        // 将设备数据转换为 DeviceDataDailyVo 对象列表
        List<DeviceDataDailyVo> deviceDataDailyVoList = new ArrayList<>();
        for (DeviceData deviceData : deviceDataList) {
            DeviceDataDailyVo vo = new DeviceDataDailyVo();
            BeanUtil.copyProperties(deviceData, vo);
            deviceDataDailyVoList.add(vo);
        }

        return deviceDataDailyVoList;
    }

    /**
     * 将时间戳转换为 LocalDateTime 类型
     * @param timestamp 时间戳
     * @return LocalDateTime 对象
     */
    private LocalDateTime convertTimestampToLocalDateTime(Long timestamp) {
        return Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    @Override
public List<Map<String,Object>> queryDeviceDataListByWeek(String iotId, Long startTime, Long endTime, String functionId) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    // 将时间戳转换为 LocalDateTime 类型
    LocalDateTime startDateTime = convertTimestampToLocalDateTime(startTime);
    LocalDateTime endDateTime = convertTimestampToLocalDateTime(endTime);

        LocalDate startDate = startDateTime.toLocalDate();
        LocalDate endDate = endDateTime.toLocalDate();
        List<String > dataList = new ArrayList<>();
    //时间周一至周日
        while(startDate.isBefore(endDate.plusDays(1))){
            dataList.add(startDate.toString());
            startDate = startDate.plusDays(1);
        }
    // 格式化 LocalDateTime 为字符串
    String startTimestamp = startDateTime.format(formatter);
    String endTimestamp = endDateTime.format(formatter);

    Map<String,Object> deviceDataList = deviceDataMapper.selectDeviceDataByWeek(iotId, startTimestamp, endTimestamp, functionId,dataList);

        List<Map<String,Object>> list = new ArrayList<>();
        deviceDataList.forEach((key,value)->{
        Map<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("dateTime",key);
        objectObjectHashMap.put("dataValue",value);
        list.add(objectObjectHashMap);
    });
    // 将设备数据转换为 DeviceDataDailyVo 对象列表
    /*List<DeviceDataDailyVo> deviceDataWeekList = new ArrayList<>();
    for (Map<String, Object> deviceData : deviceDataList) {*/
        // 检查 data_value 是否为空，如果为空则设置为 0
        /*if (deviceData.getDataValue() == null) {
            deviceData.setDataValue("0");
        }

        // 设置 create_time 字段为当前时间
        deviceData.setCreateTime(new DateTime(LocalDateTime.now()));

        DeviceDataDailyVo vo = new DeviceDataDailyVo();
        BeanUtil.copyProperties(deviceData, vo);
        deviceDataWeekList.add(vo);

        // 插入数据到 device_data 表
        try {
            deviceDataMapper.insertDeviceData(deviceData);
        } catch (Exception e) {
            log.error("插入 device_data 失败: " + e.getMessage(), e);
        }*/


    return list;
}

/*    public List<DeviceDataDailyVo> queryDeviceDataListByWeek2(String iotId, Long startTime, Long endTime, String functionId) {
        LocalDateTime startDateTime = convertTimestampToLocalDateTime(startTime);
        LocalDateTime endDateTime = convertTimestampToLocalDateTime(endTime);


        // 获取设备数据列表
        List<DeviceData> deviceDataList = deviceDataMapper.selectDeviceDataByWeek(iotId, startDateTime, endDateTime, functionId);

        // 将设备数据转换为 DeviceDataDailyVo 对象列表
        List<DeviceDataDailyVo> deviceDataWeekList = new ArrayList<>();
        for (DeviceData deviceData : deviceDataList) {
            // 检查 data_value 是否为空，如果为空则设置为 0
            if (deviceData.getDataValue() == null) {
                deviceData.setDataValue(0);
            }

            DeviceDataDailyVo vo = new DeviceDataDailyVo();
            BeanUtil.copyProperties(deviceData, vo);
            deviceDataWeekList.add(vo);

            // 插入数据到 device_data 表
            deviceDataMapper.insertDeviceData(deviceData);
        }

        return deviceDataWeekList;
    }*/



}
